package com.neuronbit.businessflow.intellij.lang;

import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.psi.tree.IElementType;
import com.neuronbit.businessflow.intellij.BpmLanguage;
import com.neuronbit.businessflow.intellij.antlr.BpmLexer;
import com.neuronbit.businessflow.intellij.antlr.BpmParser;
import org.antlr.intellij.adaptor.lexer.ANTLRLexerAdaptor;
import org.antlr.intellij.adaptor.lexer.PSIElementTypeFactory;
import org.antlr.intellij.adaptor.lexer.TokenIElementType;
import org.jetbrains.annotations.NotNull;

import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;

/**
 * The type Bpm syntax highlighter.
 */
public class BpmSyntaxHighlighter extends SyntaxHighlighterBase {
    private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0];
    /**
     * The constant ID_KEY.
     */
    public static final TextAttributesKey ID_KEY =
            createTextAttributesKey("SAMPLE_ID", DefaultLanguageHighlighterColors.INSTANCE_FIELD);
    /**
     * The constant KEYWORD_KEY.
     */
    public static final TextAttributesKey KEYWORD_KEY =
            createTextAttributesKey("SAMPLE_KEYWORD", DefaultLanguageHighlighterColors.KEYWORD);
    /**
     * The constant STRING_KEY.
     */
    public static final TextAttributesKey STRING_KEY =
            createTextAttributesKey("SAMPLE_STRING", DefaultLanguageHighlighterColors.STRING);
    /**
     * The constant LINE_COMMENT_KEY.
     */
    public static final TextAttributesKey LINE_COMMENT_KEY =
            createTextAttributesKey("SAMPLE_LINE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT);
    /**
     * The constant BLOCK_COMMENT_KEY.
     */
    public static final TextAttributesKey BLOCK_COMMENT_KEY =
            createTextAttributesKey("SAMPLE_BLOCK_COMMENT", DefaultLanguageHighlighterColors.BLOCK_COMMENT);

    /**
     * The constant DATA_TYPE_KEY.
     */
    public static final TextAttributesKey DATA_TYPE_KEY =
            createTextAttributesKey("DATA_TYPE_KEY", DefaultLanguageHighlighterColors.CLASS_NAME);

    /**
     * The constant DATA_TYPE_DIMENSION_KEY.
     */
    public static final TextAttributesKey DATA_TYPE_DIMENSION_KEY =
            createTextAttributesKey("DATA_TYPE_DIMENSION_KEY", DefaultLanguageHighlighterColors.PARAMETER);

    /**
     * The constant NUMBER_KEY.
     */
    public static final TextAttributesKey NUMBER_KEY =
            createTextAttributesKey("NUMBER_KEY", DefaultLanguageHighlighterColors.NUMBER);

    static {
        PSIElementTypeFactory.defineLanguageIElementTypes(BpmLanguage.INSTANCE,
                BpmParser.VOCABULARY,
                BpmParser.ruleNames);

    }

    @NotNull
    @Override
    public Lexer getHighlightingLexer() {
        BpmLexer lexer = new BpmLexer(null);
        return new ANTLRLexerAdaptor(BpmLanguage.INSTANCE, lexer);
    }

    @NotNull
    @Override
    public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
        if (!(tokenType instanceof TokenIElementType elementType)) {
            return EMPTY_KEYS;
        }
        int antlrTokenType = elementType.getANTLRTokenType();
        TextAttributesKey attrKey;
        switch (antlrTokenType) {
            case BpmLexer.STRING:
                attrKey = STRING_KEY;
                break;
            case BpmLexer.ID:
            case BpmLexer.PARENT:
            case BpmLexer.STYLE:
            case BpmLexer.VERTEX:
            case BpmLexer.AS:
            case BpmLexer.EDGE:
            case BpmLexer.SOURCE:
            case BpmLexer.TARGET:
            case BpmLexer.VALUE:
            case BpmLexer.NAME:
            case BpmLexer.DESCRIPTION:
            case BpmLexer.CALLABLE:
            case BpmLexer.METHOD:
            case BpmLexer.HEIGHT:
            case BpmLexer.WIDTH:
            case BpmLexer.TYPE:
            case BpmLexer.X:
            case BpmLexer.Y:
            case BpmLexer.RELATIVE:
            case BpmLexer.INDEX:
                attrKey = ID_KEY;
                break;
            case BpmLexer.MXCELL:
            case BpmLexer.MXPOINT:
            case BpmLexer.ROOT:
            case BpmLexer.MXGRAPHMODEL:
            case BpmLexer.MXGEOMETRY:
            case BpmLexer.ARRAY:
            case BpmLexer.PARAM:
            case BpmLexer.RETURN:
            case BpmLexer.AUTO_TASK:
            case BpmLexer.STATEFUL_TASK:
            case BpmLexer.CALL:
            case BpmLexer.RETURN_VALUE:
            case BpmLexer.FLOW:
            case BpmLexer.DECISION:
            case BpmLexer.SWITCH_TASK:
            case BpmLexer.EXCEPTION_HANDLER:
            case BpmLexer.FINALLY_HANDLER:
            case BpmLexer.FORK:
            case BpmLexer.JOIN:
            case BpmLexer.START:
            case BpmLexer.END:
                attrKey = DATA_TYPE_KEY;
                break;
            default:
                attrKey = KEYWORD_KEY;
        }
        return new TextAttributesKey[]{attrKey};
    }
}
